package com.boarsoft.dao.sharding.oceanbase.executor;

import java.lang.reflect.UndeclaredThrowableException;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.dao.sharding.executor.SqlCallBack;
import com.boarsoft.dao.sharding.executor.SqlRouteExecutor;
import com.boarsoft.dao.sharding.executor.SqlVoidCallBack;
import com.boarsoft.dao.sharding.oceanbase.mybatis.inspector.RouteCondition;
import com.boarsoft.dao.sharding.oceanbase.mybatis.inspector.RouteParameters;

/**
 *
 * 指定分片执行SQL的API
 *
 */
public class DbpSqlRouteExecutor implements SqlRouteExecutor {
	/**
	 * 指定分库分表执行sql(带返回值)
	 *
	 * @param tableIndex
	 *            分库分表位
	 * @param callBack
	 *            回调函数
	 * @return 执行结果
	 */
	@Override
	public Object executeQuery(String tableIndex, SqlCallBack callBack) {
		try {
			RouteParameters routeParameters = RouteCondition.newRouteParameters();
			routeParameters.setGroupId(tableIndex);
			return callBack.doExecute();
		} catch (Exception ex) {
			throw ex;
		} catch (Throwable t) {
			throw new UndeclaredThrowableException(t);
		} finally {
			RouteCondition.clear();
		}
	}

	/**
	 * 指定分库分表执行sql(无返回值)
	 *
	 * @param tableIndex
	 *            分库分表位(默认百表范围是00~99)
	 * @param callBack
	 *            回调函数
	 */
	@Override
	public void execute(String tableIndex, SqlVoidCallBack callBack) {
		try {
			RouteParameters routeParameters = RouteCondition.newRouteParameters();
			routeParameters.setGroupId(tableIndex);
			callBack.doExecute();
		} catch (Exception ex) {
			throw ex;
		} catch (Throwable t) {
			throw new UndeclaredThrowableException(t);
		} finally {
			RouteCondition.clear();
		}
	}

	/**
	 * 指定分库分表执行sql(无返回值,独立事务)
	 *
	 * @param tableIndex
	 *            分库分表位(默认百表范围是00~99)
	 * @param callBack
	 *            回调函数
	 */
	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void executeNewTransaction(String tableIndex, SqlVoidCallBack callBack) {
		try {
			RouteParameters routeParameters = RouteCondition.newRouteParameters();
			routeParameters.setGroupId(tableIndex);
			callBack.doExecute();
		} catch (Exception ex) {
			throw ex;
		} catch (Throwable t) {
			throw new UndeclaredThrowableException(t);
		} finally {
			RouteCondition.clear();
		}
	}
}